import logging

from flask import Blueprint, request, current_app,  jsonify
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
import re       # re库是用于处理正则表达式的库
import requests
import json
# from app.models import db, User, Product  现在暂时用不到数据库，后面会用到
import app.utils as utils
import logging
import time
from datetime import datetime, timedelta

# 创建一个名为ui_controller的蓝图，并返回一个名为ui_controller的蓝图对象（将来在app.py中使用它）
ui_controller = Blueprint('ui_controller', __name__)

# 统一为每个请求打印日志，通过“蓝图.before_request”和“蓝图.after_request”
@ui_controller.before_request
def log_request_info():
    current_app.logger.info(f"收到请求: {request.method} {request.url}")
@ui_controller.after_request
def log_response_info(response):
    current_app.logger.info(f"响应状态码: {response.status_code}")
    return response

# 下面开始是ui_controller蓝图下的所有装饰器与配套函数 ——————————————
# 使用蓝图之后，定义路由的方式稍微有些变化（仅在于从app变成了对应的Blueprint而已）
# NOTE RESTful风格规范：在定义接口时要根据接口功能选择合适请求方式：GET用于查询、POST用于操作或新增、PUT用于更新、DELETE用于删除等

@ui_controller.get('/stocklist')
@jwt_required()
def ui_stocklist():
    page = request.args.get("page", "1")  # 默认值为 1
    print(f"Requested page: {page}")
    final_list = []

    # 动态生成请求参数
    timestamp = int(time.time() * 1000)
    callback = f"jQuery37101004698719727698_{timestamp}"
    url = f"https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=1&invt=2&cb={callback}&fs=m%3A0%2Bt%3A6%2Cm%3A0%2Bt%3A80%2Cm%3A1%2Bt%3A2%2Cm%3A1%2Bt%3A23%2Cm%3A0%2Bt%3A81%2Bs%3A2048&fields=f12%2Cf13%2Cf14%2Cf1%2Cf2%2Cf4%2Cf3%2Cf152%2Cf5%2Cf6%2Cf7%2Cf15%2Cf18%2Cf16%2Cf17%2Cf10%2Cf8%2Cf9%2Cf23&fid=f3&pn={page}&pz=20&po=1&dect=1&ut=fa5fd1943c7b386f172d6893dbfba10b&wbp2u=%7C0%7C0%7C0%7Cweb&_{timestamp}"

    # 设置请求头
    headers = {
         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
         "Referer": "https://www.eastmoney.com/",
    }

    response = requests.get(url, headers=headers)
    response.raise_for_status()  # 检查 HTTP 错误

    # 更可靠的数据提取方式
    json_str = response.text.split('(', 1)[1].rsplit(')', 1)[0]
    res_dict = json.loads(json_str)

    # 关键检查：验证数据结构
    if not res_dict.get('data') or not isinstance(res_dict['data'].get('diff'), list):
        current_app.logger.error(f"API返回无效数据结构: {res_dict}")
        return utils.error("股票数据格式错误"), 500

    data_diff = res_dict['data']['diff']

    for item in data_diff:
        # 提取股票信息，保存到字典中
        stock_info = {
            '股票代码': item['f12'],
            '股票名称': item['f14'],
            '最新价': item['f2'],  # 注意这里是1297，网页上是12.97
            '涨跌幅': item['f3'],  # 注意这里是2001，网页上是20.01%
            '涨跌额': item['f4'],  # 注意这里是282，网页上是2.82
            '成交量': item['f5'],  # 注意这里是637574，网页上是‘63.76万’
            '振幅': item['f7'],  # 注意这里是1732，网页上是17.32%
            '最高': item['f15'],  # 注意这里是1691，网页上是16.91
            '最低': item['f16'],  # 注意这里是1447，网页上是14.47
            '今开': item['f17'],  # 注意这里是3000，网页上是30.00
            '昨收': item['f18'],  # 注意这里是1208，网页上是12.08
            '市盈率': item['f9'],  # 注意这里是-7366，网页上是-73.66
            '换手率': item['f8'],  # 注意这里是1784，网页上是17.84%
        }
        final_list.append(stock_info)

    return utils.success(data=final_list)


@ui_controller.post('/singlestock')
@jwt_required()
def ui_singlestock():
    request_body = request.get_json()
    stock_id = request_body.get('code')

    # step 1. 获取单股实时信息
    url_1 = f"https://push2.eastmoney.com/api/qt/stock/get?invt=2&fltt=1&cb=jQuery351004935203543461253_1747732615154&fields=f58%2Cf734%2Cf107%2Cf57%2Cf43%2Cf59%2Cf169%2Cf301%2Cf60%2Cf170%2Cf152%2Cf177%2Cf111%2Cf46%2Cf44%2Cf45%2Cf47%2Cf260%2Cf48%2Cf261%2Cf279%2Cf277%2Cf278%2Cf288%2Cf19%2Cf17%2Cf531%2Cf15%2Cf13%2Cf11%2Cf20%2Cf18%2Cf16%2Cf14%2Cf12%2Cf39%2Cf37%2Cf35%2Cf33%2Cf31%2Cf40%2Cf38%2Cf36%2Cf34%2Cf32%2Cf211%2Cf212%2Cf213%2Cf214%2Cf215%2Cf210%2Cf209%2Cf208%2Cf207%2Cf206%2Cf161%2Cf49%2Cf171%2Cf50%2Cf86%2Cf84%2Cf85%2Cf168%2Cf108%2Cf116%2Cf167%2Cf164%2Cf162%2Cf163%2Cf92%2Cf71%2Cf117%2Cf292%2Cf51%2Cf52%2Cf191%2Cf192%2Cf262%2Cf294%2Cf295%2Cf269%2Cf270%2Cf256%2Cf257%2Cf285%2Cf286%2Cf748%2Cf747&secid=0.{stock_id}&ut=fa5fd1943c7b386f172d6893dbfba10b&wbp2u=%7C0%7C0%7C0%7Cweb&dect=1&_=1747732615155"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
        "Referer": "https://www.eastmoney.com/",
    }
    res_1 = requests.get(url_1)
    res_1.raise_for_status()

    res_text = re.search(r'\{.+\}', res_1.text).group(0)
    res_dict = json.loads(res_text)

    if 'data' not in res_dict:
        print(f"⚠️ 股票基本信息获取失败，请检查股票ID: {stock_id}")
        return utils.error(message=f"未查询到相应股票，请检查股票ID:{stock_id}",code=400)

    stock_data = res_dict['data']  # 数据部分

    # 用来存储此股票的部分信息
    stock_info = {
        '股票代码': stock_data['f57'],
        '股票名称': stock_data['f58'],
        '最新价': stock_data['f43'],  # 注意这里是3349，网页上是33.49
        '涨跌幅': stock_data['f170'],  # 注意这里是17724，网页上是177.24%
        '涨跌额': stock_data['f169'],  # 注意这里是2127，网页上是21.27
        '成交量': stock_data['f47'],  # 注意这里是313573，网页上是‘31.36万’
        '振幅': stock_data['f171'],  # 注意这里是8270，网页上是82.70%
        '最高': stock_data['f44'],  # 注意这里是3900，网页上是39.00
        '最低': stock_data['f45'],  # 注意这里是2901，网页上是29.01
        '今开': stock_data['f46'],  # 注意这里是3000，网页上是30.00
        '昨收': stock_data['f60'],  # 注意这里是1208，网页上是12.08
        '市盈率': stock_data['f162'],  # 注意这里是4376，网页上是43.76 (还有可能是负数)
        '换手率': stock_data['f168'],  # 注意这里是6400，网页上是64.00%
    }

    # step 2. 获取单股历史信息
    url_2 = f"https://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get?cb=jQuery1123039504140390109543_1748446958030&lmt=0&klt=101&fields1=f1%2Cf2%2Cf3%2Cf7&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%2Cf61%2Cf62%2Cf63%2Cf64%2Cf65&ut=b2884a393a59ad64002292a3e90d46a5&secid=0.{stock_id}&_=1748446958031"
    res_2 = requests.get(url_2, headers=headers)
    res_2.raise_for_status()

    res_text = re.findall(r'{.+}', res_2.text)[0]
    if not res_text:
        print(f"⚠️ 价格曲线数据获取失败，请检查股票ID: {stock_id}")
        return utils.error(message=f"价格曲线数据获取失败，请检查股票ID:{stock_id}", code=400)

    res_dict = json.loads(res_text)

    if 'data' not in res_dict or 'klines' not in res_dict['data']:
        print(f"⚠️ 无价格曲线数据，请检查股票ID: {stock_id}")
        return utils.error(message=f"价格曲线数据获取失败，请检查股票ID:{stock_id}", code=400)

    klines = res_dict["data"]["klines"]

    latest_date_str = klines[-1].split(',')[0]
    latest_date = datetime.strptime(latest_date_str, "%Y-%m-%d")
    start_date = latest_date - timedelta(days=14)

    recent_data = []
    for entry in klines:
        date_str = entry.split(',')[0]
        current_date = datetime.strptime(date_str, "%Y-%m-%d")

        if current_date >= start_date:
            parts = entry.split(',')
            values = [float(x) for x in parts[1:]]
            # 在这里直接转换日期格式为"月-日"
            month_day = current_date.strftime("%m-%d")  # 新增日期格式转换
            recent_data.append({
                "date": month_day,  # 使用新格式
                "data": values
            })

    # 按日期排序（从新到旧）保持不变
    recent_data.sort(key=lambda x: datetime.strptime(x['date'], "%m-%d"), reverse=True)  # 修改排序依据

    price_curve = []
    rate_curve = []

    for entry in recent_data:
        if isinstance(entry, dict):
            # 日期已经是月-日格式，直接使用
            month_day = entry["date"]  # 直接获取转换后的日期
            price = entry["data"][-4]
            rate = entry["data"][-3]

            if month_day and price is not None and rate is not None:
                price_curve.append({
                    "date": month_day,  # 使用月-日格式
                    "value": price,
                })
                rate_curve.append({
                    "date": month_day,  # 使用月-日格式
                    "value": rate,
                })

    result = {
        "stock_info": [stock_info],
        "price_curve": price_curve,
        "rate_curve": rate_curve
    }

    return utils.success(data=result,message="success")



@ui_controller.get('/fund')
@jwt_required()
def ui_fund():
    fund_page = request.args.get("page", "1")
    print(f"Requested page: {fund_page}")
    final_list = []

    # 动态生成请求参数
    fund_url = f"https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=1&invt=2&cb=jQuery37107981760075789565_1748584387507&fs=b%3AMK0021%2Cb%3AMK0022%2Cb%3AMK0023%2Cb%3AMK0024%2Cb%3AMK0827&fields=f12%2Cf13%2Cf14%2Cf1%2Cf2%2Cf4%2Cf3%2Cf152%2Cf5%2Cf6%2Cf17%2Cf18%2Cf15%2Cf16&fid=f3&pn={fund_page}&pz=20&po=1&dect=1&ut=fa5fd1943c7b386f172d6893dbfba10b&wbp2u=%7C0%7C0%7C0%7Cweb&_=1748584387517"
    # 设置请求头
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
        "Referer": "https://www.eastmoney.com/",
    }

    response = requests.get(fund_url, headers=headers)
    response.raise_for_status()  # 检查 HTTP 错误

    res_text = re.findall(r'{.+}', response.text)[0]  # 使用正则表达式,获取最外层花括号里面的内容
    res_dict = json.loads(res_text)  # 使用Python内置的json模块将json字符串转化为dict列表

    # 关键检查：验证数据结构
    if not res_dict.get('data') or not isinstance(res_dict['data'].get('diff'), list):
        current_app.logger.error(f"API返回无效数据结构: {res_dict}")
        return utils.error("基金数据格式错误"), 500

    data_diff = res_dict['data']['diff']  # 获取实际的数据记录 仍是列表

    for item in data_diff:
        # 提取股票信息，保存到字典中
        fund_info = {
            '基金代码': item['f12'],
            '基金名称': item['f14'],
            '最新价': item['f2'],  # 注意这里是640，网页上是0.640
            '涨跌额': item['f4'],  # 注意这里是13，网页上是0.013
            '涨跌幅': item['f3'],  # 注意这里是207，网页上是2.07%
            '成交量': item['f5'],  # 注意这里是61504，网页上是‘6.15万’
            '成交额': item['f6'],  # 注意这里是3925730.0，网页上是‘392.57万’
            '开盘价': item['f17'],  # 注意这里是628，网页上是0.628
            '最高价': item['f15'],  # 注意这里是642，网页上是0.642
            '最低价': item['f16'],  # 注意这里是597，网页上是0.597
            '昨收': item['f18'],  # 注意这里是648，网页上是0.648
        }
        final_list.append(fund_info)

    return utils.success(data=final_list, message="Success")



